<template>
  <div class="upload">
    <v-btn fab color="orange darken-1" @click="btnClick">
      <span class='counter' v-if='uploading'>{{completed_counter}}/{{files.length}}</span>
      <v-icon v-else large color="white">mdi-plus</v-icon>
    </v-btn>
    <v-file-input
      v-model="files"
      style="display:none"
      id="file"
      multiple
      accept="image/*,video/*"
      @change="sheet=true"
    ></v-file-input>
    <!-- 上传列表 -->
    <v-dialog v-model='sheet'  width="800">
      <h1 align='center' class='title'>上传列表</h1>
      <v-list>
        <v-list-item-group>
          <v-list-item v-for='(item,index) of files' :key='item.name' color='orange darken-1'>
            <span class='mr-5'>{{index}}.</span>
            <span>{{item.name}}</span>
            <v-icon class='icon-close' @click="deleteItem(index)">mdi-close</v-icon>
          </v-list-item>
        </v-list-item-group>
      </v-list>
      <div  class='bottom'>
        <v-btn @click='files = []' class='mr-12' width=150  elevation=0>取消</v-btn>
        <v-btn @click='upload' class='ml-12' width=150  color='orange' elevation=0>开始上传</v-btn>
      </div>
      
    </v-dialog>
  </div>
</template>

<script>
import {http} from '@/utils/http'
import {cutBlob,mkMini} from '@/utils/utils'
import SparkMD5 from 'spark-md5'
export default {
  name: "upload",
  data() {
    return {
      files: [],
      //控制上传列表对话框的显示
      sheet:false,
      //文件夹hash
      hash:SparkMD5.hash(this.$store.state.user.user_id),
      //已完成上传的文件数量
      completed_counter:0,
      // 已成功上传的文件
      completed_files:[],
      //开始上传
      uploading:false,
    };
  },
  watch:{
    // 监听files,当用户删除全部上传文件时，关闭组件
    files:function(){
      if(this.files.length === 0){
        this.sheet = false
      }
    }
  },
  methods: {
    //监听按钮点击，触发input的click事件
    btnClick() {
      if(this.uploading){
        this.$store.commit('message',{color:'#2962FF',text:'上传任务未完成'})
        return false
      }
      document.getElementById("file").click()
    },
    //删除文件
    deleteItem(index){
      this.files.splice(index,1)
    },
    //上传
    async upload(){
      //关闭上传列表对话框
      this.sheet = false
      //开始上传
      this.uploading = true
      //上传
      for(let file of this.files){
        //文件切片，返回object，包括chunkArr和fileInfo
        let file_chunk = await cutBlob(file)
        //遍历切片数组，上传每个切片
        let promise_arr = file_chunk.chunkArr.map((item,index)=>{
          return new Promise(async (resolve,reject)=>{
            //构建data，包括切片内容，切片索引和文件夹哈希值
            let data = new FormData()
            data.append('chunk',item)
            data.append('hash',this.hash)
            data.append('index',index)
            const config = {
              url:'/upload/upload',
              method:'post',
              data
            }
            let result = await http(config)
            if(result.data.code === 812){
              resolve()
            }else{
              reject()
            }
          })
        })
        let result1 = await Promise.all(promise_arr).then(res=>{
          return 'success'
        }).catch(reason=>{
          return 'fail'
        })
        if(result1 == 'fail'){
          this.$store.commit('message',{color:'error',text:`${file_chunk.fileInfo.name}上传失败`})
          continue
        }
        //切片全部上传，通知服务器合并切片
        //制作迷你图
        let mini= await mkMini(file)
        const config = {
          url:'/upload/completed',
          method:'post',
          data:{
            hash:this.hash,
            chunkNum:file_chunk.fileInfo.total,
            file_name: file_chunk.fileInfo.name,
            file_size: file_chunk.fileInfo.size,
            file_type: file_chunk.fileInfo.type,
            file_mini:mini
          }
        }
        let result2 = await http(config)
        if(result2.data.code === 808){
          this.completed_counter ++
          this.completed_files.push(result2.data.data)
        }
      }
      //关闭上传
      this.uploading = false
      this.completed_counter = 0
      this.files = []
      this.$store.commit('message',{color:'success',text:'上传完成'})
      //发布事件
      this.$bus.$emit('upload',this.completed_files)
      this.completed_files = []
    },
  },
};
</script>

<style lang="scss" scoped>
.upload {
  position: fixed;
  bottom: 30px;
  right: 30px;
  z-index: 10;
}
.counter{
  color:#fff
}
h1{
  background-color: #fff;
}
.icon-close{
  position: absolute;
  right:10px;
}
.bottom{
  width:100%;
  background-color: #fff;
  border-top:1px #cacaca solid;
  display: flex;
  justify-content: center;
  align-items: center;
  padding:5px 0px;
}
.title{
  border-bottom:1px #cacaca solid;
  padding:8px 0px;
}
</style>
